package parse;
import ErrorMsg.ErrorMsg;

%% 


%implements Lexer

%function nextToken

%type java_cup.runtime.Symbol


%{
  private int comment_count = 0;
  private String result_s = "";
  private int str_l = 0;
  private int str_r = 0;

  private void newline() {
    errorMsg.newline(yychar+1);
  }

  private void err(int pos, String s) {
    errorMsg.error(pos,s);
  }

  private void err(String s) {
    err(yychar,s);
  }

  private java_cup.runtime.Symbol tok(int kind, Object value) {
    return new java_cup.runtime.Symbol(kind, yychar, yychar+yylength(), value);
  }

  private ErrorMsg errorMsg;

  Yylex(java.io.InputStream s, ErrorMsg e) {
    this(s);
    errorMsg=e;
  }

  private String escape_sequence(String seq)
  {
      char tempc = 0;
      String temps = "";
      if("\\t".equals(seq)) 
          tempc= '\t';
      else
      if("\\n".equals(seq)) 
          tempc= '\n';
      else
      if("\\".equals(seq)) 
          tempc= '\\';
      else
      if("\\\"".equals(seq))
          tempc= '"';
      else
      if(seq.length()==4 && seq.charAt(0)=='\\' && Character.isDigit(seq.charAt(1)) &&
         Character.isDigit(seq.charAt(2)) && Character.isDigit(seq.charAt(3)))
      {
         int tmp=0;
         tmp=(seq.charAt(1)-48)*100 + (seq.charAt(2)-48)*10 + (seq.charAt(3)-48);
         if(tmp<256&&tmp>=0)
         tempc= (char)tmp;
         else
         {
             err("Error: Illegal escape sequence.");
             return "";
         }
      }
      else
      if(seq.length()==3 && seq.charAt(0)=='\\' && seq.charAt(1)=='^' && seq.charAt(2)>=64 && seq.charAt(2)<= 95)
	tempc=(char)(seq.charAt(2)-64);

      if(tempc!=0)temps+=tempc;
      return temps;
  }


%}


%eofval{
	 {if(yy_lexical_state == STRING || yy_lexical_state == NEWLINE)  err("String presentation error!");
	 return tok(sym.EOF, null);
    }
%eofval}     
 
%char
%state STRING
%state NEWLINE

ALPHA=[A-Za-z]
DIGIT=[0-9]
NONNEWLINE_WHITE_SPACE_CHAR=[\ \t\b\012]
WHITE_SPACE_CHAR=[\n\r\ \t\b\012]
 
%% 

<YYINITIAL> "," { return tok(sym.COMMA,null); }
<YYINITIAL> "*" { return tok(sym.MULTI,null); }
<YYINITIAL> "(" { return tok(sym.LPAREN,null); }
<YYINITIAL> ")" { return tok(sym.RPAREN,null); }
<YYINITIAL> "." { return tok(sym.DOT,null); }
<YYINITIAL> "=" { return tok(sym.EQ,null); }
<YYINITIAL> "<>" { return tok(sym.NEQ,null); }
<YYINITIAL> "<"  { return tok(sym.LT,null); }
<YYINITIAL> "<=" { return tok(sym.LE,null); }
<YYINITIAL> ">"  { return tok(sym.GT,null); }
<YYINITIAL> ">=" { return tok(sym.GE,null); }
<YYINITIAL> "ALL" { return tok(sym.ALL,null); }
<YYINITIAL> "AND" { return tok(sym.AND,null); }
<YYINITIAL> "ANY" { return tok(sym.ANY,null); }
<YYINITIAL> "AS" { return tok(sym.AS,null); }
<YYINITIAL> "ASC" { return tok(sym.ASC,null); }
<YYINITIAL> "BY" { return tok(sym.BY,null); }
<YYINITIAL> "CREATE" { return tok(sym.CREATE,null); }
<YYINITIAL> "DELETE" { return tok(sym.DELETE,null); }
<YYINITIAL> "DESC" { return tok(sym.DESC,null); }
<YYINITIAL> "ESCAPE" { return tok(sym.ESCAPE,null); }
<YYINITIAL> "FROM" { return tok(sym.FROM,null); }
<YYINITIAL> "INSERT" { return tok(sym.INSERT,null); }
<YYINITIAL> "INTO" { return tok(sym.INTO,null); }
<YYINITIAL> "KEY" { return tok(sym.KEY,null); }
<YYINITIAL> "LIKE" { return tok(sym.LIKE,null); }
<YYINITIAL> "NOT" { return tok(sym.NOT,null); }
<YYINITIAL> "NULL" { return tok(sym.NULL,null); }
<YYINITIAL> "OR" { return tok(sym.OR,null); }
<YYINITIAL> "ORDER" { return tok(sym.ORDER,null); }
<YYINITIAL> "PRIMARY" { return tok(sym.PRIMARY,null); }
<YYINITIAL> "SELECT" { return tok(sym.SELECT,null); }
<YYINITIAL> "TABLE" { return tok(sym.TABLE,null); }
<YYINITIAL> "VALUES" { return tok(sym.VALUES,null); }
<YYINITIAL> "WHERE" { return tok(sym.WHERE,null); }
<YYINITIAL> "UPDATE" { return tok(sym.UPDATE,null); }
<YYINITIAL> "SET" { return tok(sym.SET,null); }
<YYINITIAL> "INDEX" { return tok(sym.INDEX,null); }
<YYINITIAL> "VIEW" { return tok(sym.VIEW,null); }
<YYINITIAL> "ON" { return tok(sym.ON,null); }
<YYINITIAL> "DROP" { return tok(sym.DROP,null); }
<YYINITIAL> "ALTER" { return tok(sym.ALTER,null); }
<YYINITIAL> "ADD" { return tok(sym.ADD,null); }
<YYINITIAL> "INTEGER" { return tok(sym.INTEGER,null); }
<YYINITIAL> "CHAR" { return tok(sym.CHAR,null); }
<YYINITIAL> "VARCHAR" { return tok(sym.VARCHAR,null); }
<YYINITIAL> "NATURAL" { return tok(sym.NATURAL,null); }
<YYINITIAL> "JOIN" { return tok(sym.JOIN,null); }
<YYINITIAL> "IN" { return tok(sym.IN,null); }
<YYINITIAL> "FOREIGN" { return tok(sym.FOREIGN,null); }
<YYINITIAL> "REFERENCES" { return tok(sym.REFERENCES,null); }

<YYINITIAL> "all" { return tok(sym.ALL,null); }
<YYINITIAL> "and" { return tok(sym.AND,null); }
<YYINITIAL> "any" { return tok(sym.ANY,null); }
<YYINITIAL> "as" { return tok(sym.AS,null); }
<YYINITIAL> "asc" { return tok(sym.ASC,null); }
<YYINITIAL> "by" { return tok(sym.BY,null); }
<YYINITIAL> "create" { return tok(sym.CREATE,null); }
<YYINITIAL> "delete" { return tok(sym.DELETE,null); }
<YYINITIAL> "desc" { return tok(sym.DESC,null); }
<YYINITIAL> "escape" { return tok(sym.ESCAPE,null); }
<YYINITIAL> "from" { return tok(sym.FROM,null); }
<YYINITIAL> "insert" { return tok(sym.INSERT,null); }
<YYINITIAL> "into" { return tok(sym.INTO,null); }
<YYINITIAL> "key" { return tok(sym.KEY,null); }
<YYINITIAL> "like" { return tok(sym.LIKE,null); }
<YYINITIAL> "not" { return tok(sym.NOT,null); }
<YYINITIAL> "null" { return tok(sym.NULL,null); }
<YYINITIAL> "or" { return tok(sym.OR,null); }
<YYINITIAL> "order" { return tok(sym.ORDER,null); }
<YYINITIAL> "primary" { return tok(sym.PRIMARY,null); }
<YYINITIAL> "select" { return tok(sym.SELECT,null); }
<YYINITIAL> "table" { return tok(sym.TABLE,null); }
<YYINITIAL> "values" { return tok(sym.VALUES,null); }
<YYINITIAL> "where" { return tok(sym.WHERE,null); }
<YYINITIAL> "update" { return tok(sym.UPDATE,null); }
<YYINITIAL> "set" { return tok(sym.SET,null); }
<YYINITIAL> "index" { return tok(sym.INDEX,null); }
<YYINITIAL> "view" { return tok(sym.VIEW,null); }
<YYINITIAL> "on" { return tok(sym.ON,null); }
<YYINITIAL> "drop" { return tok(sym.DROP,null); }
<YYINITIAL> "alter" { return tok(sym.ALTER,null); }
<YYINITIAL> "add" { return tok(sym.ADD,null); }
<YYINITIAL> "integer" { return tok(sym.INTEGER,null); }
<YYINITIAL> "char" { return tok(sym.CHAR,null); }
<YYINITIAL> "varchar" { return tok(sym.VARCHAR,null); }
<YYINITIAL> "natural" { return tok(sym.NATURAL,null); }
<YYINITIAL> "join" { return tok(sym.JOIN,null); }
<YYINITIAL> "in" { return tok(sym.IN,null); }
<YYINITIAL> "foreign" { return tok(sym.FOREIGN,null); }
<YYINITIAL> "references" { return tok(sym.REFERENCES,null); }

<YYINITIAL> {WHITE_SPACE_CHAR}+ { }

<YYINITIAL> "'"		
{
    result_s="";
    str_l=yychar;
    str_r=yychar;
    yybegin(STRING);
}

<STRING> \\[\ \t]*(\n|(\r\n)|\r) {newline();  yybegin(NEWLINE); }
<STRING> (\n|(\r\n)|\r) { newline(); yybegin(YYINITIAL); err("Error: Unclosed string."); }

<STRING> \\(r|n|t|[0-9][0-9][0-9]|\"|\\|"^"[@A-Z_]) 
{ str_r += result_s.length(); result_s += escape_sequence(yytext());}

<STRING> \\. { err("Error: Illegal escape sequence.");}
<STRING> "'" { yybegin(YYINITIAL); return tok(sym.STRING,result_s);  }
<STRING> . { result_s += yytext(); str_r += 1;}
<NEWLINE> [\ \t]*(\r\n|\n|\r) {newline();}
<NEWLINE> [\ \t]*\\ { yybegin(STRING); }
<NEWLINE> . { err("Error: Illegal sequence."); }

<YYINITIAL> {DIGIT}+ { 
	return tok(sym.INT,new Integer(yytext()));
}	
<YYINITIAL> {ALPHA}({ALPHA}|{DIGIT}|_)* {
	return tok(sym.ID,yytext());
}	
<YYINITIAL> . {
	err("Error: Unclosed string.");
}








